#ifndef BEZIERCUBSURF_H_
#define BEZIERCUBSURF_H_

#include <GL/glew.h>
#include <GL/glut.h>
#include <glm/glm.hpp>

#include <string.h>
#include <vector>
#include "Figure.h"

#define DETAILBEZIERSURF 5//Detalle de las normales?
#define TAMBEZIERSURF 8 // Tamaño del parche que voy a generar(total)
#define TAMPATCHBEZIER 4 //Cantidad de nodos de cada parche ingresado

using std::vector;

class BezierCubSurf: public Figure {
	public:
		BezierCubSurf(GLuint program, GLfloat ctrlpoints[TAMPATCHBEZIER][TAMPATCHBEZIER][3]);
		~BezierCubSurf(void);
		void drawSurface(glm::mat4 mat);
		void drawControlPoints();
		void drawNormals(glm::mat4 world_matrix);
		virtual void draw(GLuint program, glm::mat4 & world_matrix);

	private:
		GLfloat controlPoints[TAMPATCHBEZIER][TAMPATCHBEZIER][3];
		float surface[TAMBEZIERSURF][TAMBEZIERSURF][3];
		float normals[TAMBEZIERSURF][TAMBEZIERSURF][3];

		void calculateSurface();
		void calculateNormals();
		void calculateNormalForMiddlePoint(size_t x,size_t y,float h);
		void calculateNormalForPositBorderPoint(size_t x,size_t y,float h);
		void calculateNormalForNegBorderPoint(size_t x,size_t y,float h);
		float baseBezier(size_t n,size_t j,float t);
		long Combinatoria(long a,long b);
		long factorial(long n);
		float pow(float base,size_t exp);

		static GLfloat * static_vertex_buffer;
		static GLuint * static_index_buffer;
		static GLfloat * static_normal_buffer;
		static GLfloat * static_texture_buffer;
		static GLfloat * static_tangent_buffer;

		static GLuint static_vertex_buffer_size;
		static GLuint static_index_buffer_size;
		static GLuint static_normal_buffer_size;

		void instantiate_buffer();
		void create_vertex_buffer();
		void create_index_buffer();
		void create_normal_buffer();
		void create_texture_buffer();
		void crearDatos();

};

#endif
